'support funcs
#include once "gfxed.bi"
#include once "ext/graphics/bmp.bi"


declare sub flood_fill( byval buf_ as fb.image ptr, byval x as uinteger, byval y as uinteger, _
        byval dest_color as uinteger, byval rep_color as uinteger )

sub tool_default_destroy( byval state as tool ptr )
'does nothing, and how!
end sub



sub tool_brush( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )
    pset i,(x, y), color_
end sub

sub tool_fill( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )
    flood_fill( i, x, y, Color_, point(x,y,i) )
end sub

sub tool_line( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )

    if cast(integer ptr,state->state_) = 0 then

        state->state_ = new integer[2]
        cast(integer ptr,state->state_)[0] = x
        cast(integer ptr,state->state_)[1] = y

    else
        if cast(integer ptr, state->state_)[0] = x andalso cast(integer ptr, state->state_)[1] = y then return
        line i, (cast(integer ptr, state->state_)[0], cast(integer ptr, state->state_)[1])-(x,y), color_
        delete[] cast(integer ptr,state->state_)
        state->state_ = 0

    end if

end sub

sub tool_circle( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )

    if cast(integer ptr,state->state_) = 0 then

        state->state_ = new integer[2]
        cast(integer ptr,state->state_)[0] = x
        cast(integer ptr,state->state_)[1] = y

    else

        if cast(integer ptr, state->state_)[0] = x andalso cast(integer ptr, state->state_)[1] = y then return
        circle i, (cast(integer ptr, state->state_)[0], cast(integer ptr, state->state_)[1]), sqr( (cast(integer ptr, state->state_)[0] - x)^2 + (cast(integer ptr, state->state_)[1] - y)^2 ), color_
        delete[] cast(integer ptr,state->state_)
        state->state_ = 0

    end if

end sub

sub tool_box( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )

    if cast(integer ptr,state->state_) = 0 then

        state->state_ = new integer[2]
        cast(integer ptr,state->state_)[0] = x
        cast(integer ptr,state->state_)[1] = y

    else

        if cast(integer ptr, state->state_)[0] = x andalso cast(integer ptr, state->state_)[1] = y then return
        line i, (cast(integer ptr, state->state_)[0], cast(integer ptr, state->state_)[1])-(x,y), color_, B
        delete[] cast(integer ptr,state->state_)
        state->state_ = 0

    end if

end sub

sub tool_eraser( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )
    pset i,(x,y), rgb(255,0,255)
end sub

sub tool_clear( byval i as fb.image ptr, byval x as integer, byval y as integer, byval color_ as integer, byval state as tool ptr )
    line i,(0,0)-(i->width,i->height),rgb(255,0,255),BF
end sub

sub tool_line_destroy( byval state as tool ptr )
    if state->state_ <> 0 then delete[] cast(integer ptr, state->state_)
    state->state_ = 0
end sub

destructor tool

    this.destroy(@this)
    imagedestroy( this.toolbox )
    if this.cursor <> 0 then delete this.cursor

end destructor

constructor tool

    this.state_ = 0
    this.cursor = 0
    this.toolbox = 0
    this.this_ = @this
    this.destroy = @tool_default_destroy

end constructor

function tool_brush_cursor( ) as ext.gfx.sprite ptr

    var t = new ext.gfx.sprite
    t->init(4)

    t->setImage(0, imagecreate(8,8,rgb(255,0,255),32))
    circle t->getImage(0),(3,3),3,rgb(0,0,0)

    t->setImage(1, imagecreate(8,8,rgb(255,0,255),32))
    circle t->getImage(1),(3,3),3,rgb(255,255,255)

    t->setImage(2, imagecreate(8,8,rgb(255,0,255),32))
    circle t->getImage(2),(3,3),2,rgb(0,0,0)

    t->setImage(3, imagecreate(8,8,rgb(255,0,255),32))
    pset t->getImage(3),(3,3),rgb(255,255,255)

    return t

end function

function load_tools() as tool ptr

    var t = new tool[num_tools]

    'now setup our tools
    t[0].use = @tool_brush
    t[0].toolname = "Pen"
    t[0].toolbox = ext.gfx.bmp.load("data/brush.bmp")
    t[0].cursor = tool_brush_cursor()


    t[1].use = @tool_fill
    t[1].toolname = "Fill"
    t[1].toolbox = ext.gfx.bmp.load("data/fill.bmp")

    t[2].use = @tool_line
    t[2].destroy = @tool_line_destroy
    t[2].toolname = "Line"
    t[2].toolbox = ext.gfx.bmp.load("data/line.bmp")

    t[3].use = @tool_circle
    t[3].destroy = @tool_line_destroy
    t[3].toolname = "Circle"
    t[3].toolbox = ext.gfx.bmp.load("data/circle.bmp")

    t[4].use = @tool_box
    t[4].destroy = @tool_line_destroy
    t[4].toolname = "Box"
    t[4].toolbox = ext.gfx.bmp.load("data/box.bmp")

    t[5].use = @tool_eraser
    t[5].toolname = "Eraser"
    t[5].toolbox = ext.gfx.bmp.load("data/eraser.bmp")

    t[6].use = @tool_clear
    t[6].toolname = "Clear"
    t[6].toolbox = ext.gfx.bmp.load("data/clear.bmp")
    t[6].cursor = new ext.gfx.sprite
    t[6].cursor->init(1)
    t[6].cursor->setImage(0,ext.gfx.bmp.load("data/clear.bmp"))

    'special cases
    t[7].toolname = "Save"
    t[7].toolbox = ext.gfx.bmp.load("data/save.bmp")

    t[8].toolname = "Load"
    t[8].toolbox = ext.gfx.bmp.load("data/load.bmp")

    t[9].toolname = "Colors"
    t[9].toolbox = ext.gfx.bmp.load("data/pal.bmp")

    t[10].toolname = "Dropper"
    t[10].toolbox = ext.gfx.bmp.load("data/dropr.bmp")

    t[11].toolname = "Grid"
    t[11].toolbox = ext.gfx.bmp.load("data/grid.bmp")
    
    t[12].toolname = "Help"
    t[12].toolbox = ext.gfx.bmp.load("data/help.bmp")

    return t

end function

sub draw_input( x as uinteger, y as uinteger, byref taco_ as string, _cdata as any ptr = ext.null )

var b = cast( box ptr, _cdata )
with *b
        line (.x1,.y1)-(.x2,.y2), rgb(169,169,169), BF
end with
draw string (x, y), taco_,0, , trans

end sub

function linefill( byval buf_ as fb.image ptr, byval x as uinteger, byval y as uinteger, _
        byval dest_color as uinteger, byval rep_color as uinteger ) as ext.bool ' this will be used for advanced fill algo

        var retval = ext.false

        for n as uinteger = x to 0 step - 1

                if point(n,y,buf_) = rep_color then
                        pset buf_,(n,y), dest_color
                        retval = ext.true
                else
                        exit for
                end if
        next
        for n as uinteger = x+1 to buf_->width -1
                if point(n,y,buf_) = rep_color then
                        pset buf_,(n,y), dest_color
                        retval = ext.true
                else
                        exit for
                end if
        next

        return retval

end function

sub flood_fill( byval buf_ as fb.image ptr, byval x as uinteger, byval y as uinteger, _
        byval dest_color as uinteger, byval rep_color as uinteger )

        if rep_color = dest_color then
                return
        end if


        for n as uinteger = y to 0 step - 1

                if point(x,n,buf_) = rep_color then
                        linefill buf_,x,n, dest_color, rep_color
                else
                        exit for
                end if
        next
        for n as uinteger = y+1 to buf_->height -1
                if point(x,n,buf_) = rep_color then
                        linefill buf_,x,n, dest_color, rep_color
                else
                        exit for
                end if
        next
end sub

